﻿#ifndef _CCWATER_INCLUDE
#define _CCWATER_INCLUDE

#include "CCWaterInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"



struct WaterVertexInput{
    float4 vertex             : POSITION;
    float2 texcoord           : TEXCOORD0; //uv
    
    UNITY_VERTEX_INPUT_INSTANCE_ID

};

struct WaterVertexOutput{
    float4 clipPos          : SV_POSITION;
    float2 uv                : TEXCOORD0;
    float3 posWS             : TEXCOORD1;
    float4 screenPos         : TEXCOORD2;
    half3 normalWS             :TEXCOORD3;
    float3 viewDirWS           : TEXCOORD4;
    
    
    
    
    UNITY_VERTEX_INPUT_INSTANCE_ID
    UNITY_VERTEX_OUTPUT_STEREO
};



half3 BlendNormal(half3 n1, half3 n2){
     return normalize(half3(n1.xy + n2.xy, n1.z*n2.z));
}

float3 mod2D289( float3 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }

float2 mod2D289( float2 x ) { return x - floor( x * ( 1.0 / 289.0 ) ) * 289.0; }

float3 permute( float3 x ) { return mod2D289( ( ( x * 34.0 ) + 1.0 ) * x ); }

float snoise( float2 v )
{
    const float4 C = float4( 0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439 );
    float2 i = floor( v + dot( v, C.yy ) );
    float2 x0 = v - i + dot( i, C.xx );
    float2 i1;
    i1 = ( x0.x > x0.y ) ? float2( 1.0, 0.0 ) : float2( 0.0, 1.0 );
    float4 x12 = x0.xyxy + C.xxzz;
    x12.xy -= i1;
    i = mod2D289( i );
    float3 p = permute( permute( i.y + float3( 0.0, i1.y, 1.0 ) ) + i.x + float3( 0.0, i1.x, 1.0 ) );
    float3 m = max( 0.5 - float3( dot( x0, x0 ), dot( x12.xy, x12.xy ), dot( x12.zw, x12.zw ) ), 0.0 );
    m = m * m;
    m = m * m;
    float3 x = 2.0 * frac( p * C.www ) - 1.0;
    float3 h = abs( x ) - 0.5;
    float3 ox = floor( x + 0.5 );
    float3 a0 = x - ox;
    m *= 1.79284291400159 - 0.85373472095314 * ( a0 * a0 + h * h );
    float3 g;
    g.x = a0.x * x0.x + h.x * x0.y;
    g.yz = a0.yz * x12.xz + h.yz * x12.yw;
    return 130.0 * dot( m, g );
}

WaterVertexOutput WaterVertex(WaterVertexInput input){
    WaterVertexOutput o;
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_TRANSFER_INSTANCE_ID(input, o);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    
    o.uv = input.texcoord;
    o.posWS = TransformObjectToWorld(input.vertex.xyz);
    
    o.clipPos = TransformWorldToHClip(o.posWS);
    
    o.viewDirWS =  normalize(_WorldSpaceCameraPos.xyz - o.posWS);
    return o;
} 

half4 WaterFragment(WaterVertexOutput input) : SV_Target{

    half2 size = half2(100,100);
    half mulTime = _Time.y * _Speed;
    half2 temp_cast = mulTime.xx;
    half2 uv_texcoord = input.uv * size + temp_cast;
    
    half2 temp_cast_1 = (1 - mulTime).xx;
    half2 uv_texcoord1 = input.uv * size + temp_cast_1;
   
    
    half3 normal1 = UnpackNormalRGB(tex2D(_NormalMap, uv_texcoord), _NormalStrength);
    half3 normal2 = UnpackNormalRGB(tex2D(_NormalMap, uv_texcoord1), _NormalStrength);
    half3 normal = BlendNormal(normal1,normal2);
    
    half3 worldPos = input.posWS;
    half2 tempOutput = worldPos.xz;
    half2 panner1 = 0.1 * _Time.y * half2(1, 0)  + tempOutput;
    half simplePerlin1 = snoise(panner1);
    
    half2 panner2 = 0.1 * _Time.y * float2(-1, 0) + tempOutput;
    half simplePerlin2 = snoise(panner2);
    
    half clampResult = clamp(simplePerlin1 + simplePerlin2, 0,1);
    
    half largeNoisePattern = clampResult;
    half4 ase_screenPos = half4(input.clipPos.xyz , input.clipPos.w + 0.00000001);
   
    half2 depthUv = half2(0,0);
    half rawD = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_ScreenTextures_linear_clamp,depthUv);
    half eyeDepth = LinearEyeDepth(rawD, _ZBufferParams);
    half edgeEffect =abs(eyeDepth - input.clipPos.w);
    
    half foamWater = 1 - step(largeNoisePattern, edgeEffect);
    half foamEdge = 1 - step(0.1 + (_SinTime.w  - -1.0) * (0.3 -0,.1) / (1.0 - -1.0), edgeEffect);
    
    half topWater = saturate(1 - edgeEffect);
    half deepWater = saturate(pow(edgeEffect, _WaterFalloff));
    
    half4 lerpResult = lerp(_BottomColor, _MidColor, deepWater);
    
    half3 albedo = saturate(
        saturate((_FoamColor * foamWater) + (_FoamColor * foamEdge)) + (_TopColor * topWater) + lerpResult
    ).rgb;
    
    half3 normalWS = TransformObjectToWorldNormal(normal);
    half frensnelNDotV = dot(normalWS, input.viewDirWS);
    half fresnelNode = (0 + 1 * pow(1 - frensnelNDotV, _Smoothness));
    half smoothness = saturate(fresnelNode);
    
    half fresnelNode1 = 0.2 + 1.0 * pow(1 - fresnelNode, _Transparency); 
    half alpha = saturate(fresnelNode);

    return half4(albedo,1);
}


#endif